package com.sugon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import com.sugon.dao.ModuleTimesPositionDao;
import com.sugon.entity.ModulPositionCorrelationEntity;
import com.sugon.entity.ModuleTimesPositionEntity;
import com.sugon.modules.utils.DateUtil;
import com.sugon.service.ModulPositionCorrelationService;
import com.sugon.service.ModuleTimesPositionService;
import lombok.Data;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 模具位置模次每日同步记录Service实现类
 *
 * @author YuXD
 * @date 2023-02-28 16:17:12
 */
@Service("moduleTimesPositionService")
public class ModuleTimesPositionServiceImpl implements ModuleTimesPositionService {
    @Resource
    private ModuleTimesPositionDao moldTimesPositionDao;
    @Resource
    private ModulPositionCorrelationService moldPositionService;

    /**
     * 查询某副模具 指定日期区间内各位置的模次采集情况
     *
     * @param moldId    模具ID
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    private List<ModuleTimesPositionEntity> queryMoldPostionTimesCollectData(String moldId, String startDate, String endDate) {
        /*
            需要判断startDate和endDate是否是同一天
            如果不是同一天，则表示要查看区间内的
            如果是同一天，则表示查看具体某一天的采集信息
         */
        if (!startDate.equals(endDate)) {
            // 不是同一天
            startDate += " 0:00:00";
            endDate += " 23:59:59";
        } else {
            endDate = null;
        }
        List<ModuleTimesPositionEntity> collectDataList = moldTimesPositionDao.selectList(moldId, startDate, endDate);
        return Optional.ofNullable(collectDataList).orElse(CollectionUtil.newArrayList());
    }

    /**
     * 获取某一模具位置 截止到collectDate 最近一次的模次累计数
     *
     * @param moldPosId
     * @param collectDate
     * @return
     */
    private Integer getLastestMoldTimes(String moldPosId, String collectDate) {
        collectDate += " 0:00:00";
        ModuleTimesPositionEntity lastestMoldTimesCollectRecord = moldTimesPositionDao.getLastestMoldTimesCollectRecord(moldPosId, collectDate);
        return lastestMoldTimesCollectRecord == null ? 0 : lastestMoldTimesCollectRecord.getAccumulationTimes();
    }


    @Override
    public Map<String, Object> generateMoldPositionTimesPreviewData(String moldId, Integer days) {

        // 声明模具备件寿命预览模板数据
        Map<String, Object> moldPosTimesPreviewTemplateData = MapUtil.newHashMap(2);
        // 获取采集日期列表
        List<String> collectDateList = DateUtil.generateDateList(days);
        // 获取模具位置列表
        List<ModulPositionCorrelationEntity> moldPositionList = moldPositionService.queryListByMoldId(moldId);
        // 获取这幅模具各位置的采集数据列表
        List<ModuleTimesPositionEntity> collectDataList = queryMoldPostionTimesCollectData(moldId, collectDateList.get(0), collectDateList.get(days - 1));
        // 获取模具位置模次分组
        Map<String, List<ModuleTimesPositionEntity>> moldPosTimesGroup = collectDataList.stream().collect(Collectors.groupingBy(ModuleTimesPositionEntity::getMoldPosId));

        // 设置顶部日期列表
        List<MoldTimesDay> dayList = CollectionUtil.newArrayList();
        for (int i = 0; i < days; i++) {
            String collectDate = collectDateList.get(i);
            // 设置
            dayList.add(new MoldTimesDay(collectDateList.get(i), "t.value" + i));
        }
        // 设置模次列表
        List<Map<String, Object>> moldPosMapList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(moldPositionList)) {
            Map<String, Object> moldPosMap = null;
            for (ModulPositionCorrelationEntity moldPos : moldPositionList) {
                moldPosMap = BeanUtil.beanToMap(moldPos);

                // 获取当前这个位置的 模次采集书记
                List<ModuleTimesPositionEntity> posCollectDatas = moldPosTimesGroup.get(moldPos.getId());
                Map<String, List<ModuleTimesPositionEntity>> collectDateGroup = null;
                if (CollectionUtil.isNotEmpty(posCollectDatas)) {
                    collectDateGroup = posCollectDatas.stream().collect(Collectors.groupingBy(collectRecord -> cn.hutool.core.date.DateUtil.formatDate(collectRecord.getProductionDate())));
                }
                /*
                    尝试获取某个位置 在某个时间区间内 模次采集记录
                    如果未采集过，那么每天都默认为0
                    如果采集过：尝试获取某一天的采集结果
                        如果这一天采集过，则直接填写实际的
                        如果这一天没有记录，则尝试获取最近一次有记录的模次数
                 */
                for (int i = 0; i < days; i++) {
                    String collectDate = collectDateList.get(i);
                    if (collectDateGroup != null && collectDateGroup.containsKey(collectDate)) {
                        moldPosMap.put("value" + i, collectDateGroup.get(collectDate).get(0).getAccumulationTimes());
                    } else {
                        if (i == 0) {
                            // 如果是第一次，则尝试获取这个位置最近一次的采集时间
                            moldPosMap.put("value" + i, getLastestMoldTimes(moldPos.getId(), collectDate));
                        } else {
                            moldPosMap.put("value" + i, moldPosMap.get("value" + (i - 1)));
                        }
                    }
                }
                moldPosMapList.add(moldPosMap);
            }
        }

        // 一个设备放到一起
        moldPosTimesPreviewTemplateData.put("moldPosMapList", moldPosMapList);
        // 设置要查看的日期
        moldPosTimesPreviewTemplateData.put("dayList", dayList);
        return moldPosTimesPreviewTemplateData;
    }

    @Data
    private class MoldTimesDay {

        /**
         * 每天的日期
         */
        private String productionDate;

        private String matchKey;

        public MoldTimesDay(String productionDate, String matchKey) {
            this.productionDate = productionDate;
            this.matchKey = matchKey;
        }

    }

    @Override
    public ModuleTimesPositionEntity queryObject(String id) {
        return moldTimesPositionDao.queryObject(id);
    }

    @Override
    public List<ModuleTimesPositionEntity> queryList(Map<String, Object> map) {
        return moldTimesPositionDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return moldTimesPositionDao.queryTotal(map);
    }

    @Override
    public int save(ModuleTimesPositionEntity moduleTimesPosition) {
        moduleTimesPosition.setId(RandomUtil.randomString(32));
        return moldTimesPositionDao.save(moduleTimesPosition);
    }

    @Override
    public int update(ModuleTimesPositionEntity moduleTimesPosition) {
        return moldTimesPositionDao.update(moduleTimesPosition);
    }

    @Override
    public int delete(String id) {
        return moldTimesPositionDao.delete(id);
    }

    @Override
    public int deleteBatch(String[] ids) {
        return moldTimesPositionDao.deleteBatch(ids);
    }

}
